package cn.edu.xust.api.controller;

import cn.edu.xust.Ro.MulHotelEleRo;
import cn.edu.xust.Ro.MulHotelWtRo;
import cn.edu.xust.configuration.exception.Default200Exception;
import cn.edu.xust.configuration.exception.ErrorConstant;
import cn.edu.xust.entity.DeviceEntity;
import cn.edu.xust.service.DeviceService;
import cn.edu.xust.service.ElecdataService;
import cn.edu.xust.service.WtdataService;
import cn.edu.xust.util.R;
import cn.edu.xust.util.RedisUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.TextStyle;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;


/**
 * @author ufo
 * @email 2575829997@qq.com
 * @date 2024-03-27 18:09:23
 */
@RestController
@RequestMapping("/api/device")
public class ApiDeviceController {
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private ElecdataService elecdatas;
    @Autowired
    private WtdataService wtdataService;

    /**
     * 列表
     */
    @RequestMapping("/list")
    public R list(@RequestParam(value = "sign") String sign, @RequestBody JSONObject jsonObject) {
        String hotelid = jsonObject.getString("hotelid");
        String roomname = jsonObject.getString("roomname");
        List<DeviceEntity> byHotelRoom = deviceService.getByHotelRoom(hotelid, roomname);
        return R.ok().put("data", byHotelRoom);
    }


    @PostMapping("/getcalcheck")
    public R getcalcheck(@RequestBody JSONObject jsonObject) throws Default200Exception {


        String hotelid = jsonObject.getString("hotelid");
        Integer year = jsonObject.getInteger("year");
        Integer month = jsonObject.getInteger("month");

        // 获取当前年月
        YearMonth currentYearMonth = YearMonth.now();
        // 构建输入的年月
        YearMonth inputYearMonth = YearMonth.of(year, month);

        // 检查日期是否过早或过晚
        if (inputYearMonth.isBefore(YearMonth.of(2024, 4))) {
            throw new Default200Exception(ErrorConstant.date_so_early);
        }
        if (inputYearMonth.isAfter(currentYearMonth)) {
            throw new Default200Exception(ErrorConstant.date_so_late);
        }

        List<DayInfo> calendarData = generateCalendarData(year, month);

        for (DayInfo dayInfo : calendarData) {
            Date date = dayInfo.getDate();
            String formattedDate = formatDate(date, "yyyy-MM-dd");
            String key = "calcheck:" + hotelid + ":" + formattedDate;
            Object o = redisUtil.get(key);
            if (o == null) {
                //现查 在存入redis
                List<MulHotelEleRo> ele = elecdatas.getByHType(hotelid, "ele", formattedDate);
                List<MulHotelWtRo> coldwt = wtdataService.getByHType(hotelid, "coldwt", formattedDate);
                List<MulHotelWtRo> hotwt = wtdataService.getByHType(hotelid, "hotwt", formattedDate);

                String key2 = "targetnumconfig:" + hotelid;
                Object o1 = redisUtil.get(key2);
                String config = "0:0:0";
                if (o1 != null) {
                    config = (String) o1;
                }
                String[] split = config.split(":");
                ArrayList<CheckDate> checkDates = new ArrayList<>();
                CheckDate checkDate = new CheckDate();
                checkDate.setTagetnum(split[0]);
                checkDate.setRealnum(ele.size() + "");
                checkDate.setName("ele");
                checkDate.setState(split[0].equals((ele.size() + "")) ? "eq" : "neq");

                CheckDate checkDate2 = new CheckDate();
                checkDate2.setTagetnum(split[1]);
                checkDate2.setRealnum(coldwt.size() + "");
                checkDate2.setName("coldwt");
                checkDate2.setState(split[1].equals((coldwt.size() + "")) ? "eq" : "neq");

                CheckDate checkDate3 = new CheckDate();
                checkDate3.setTagetnum(split[2]);
                checkDate3.setRealnum(hotwt.size() + "");
                checkDate3.setName("hotwt");
                checkDate3.setState(split[2].equals((hotwt.size() + "")) ? "eq" : "neq");

                checkDates.add(checkDate);
                checkDates.add(checkDate2);
                checkDates.add(checkDate3);
                dayInfo.setChecklist(checkDates);
                redisUtil.set(key, checkDates);
            } else {
                List<CheckDate> o1 = (List<CheckDate>) o;
                dayInfo.setChecklist(o1);
            }
        }
        return R.ok().put("data", calendarData);
    }


    @PostMapping("/gettargteconfig")
    public R gettargteconfig(@RequestBody JSONObject jsonObject) throws Default200Exception {
        String hotelid = jsonObject.getString("hotelid");
        String key2 = "targetnumconfig:" + hotelid;
        Object o1 = redisUtil.get(key2);
        String config = "0:0:0";
        if (o1 != null) {
            config = (String) o1;
        }
        return R.ok().put("data", config);
    }

    @PostMapping("/settargteconfig")
    public R settargteconfig(@RequestBody JSONObject jsonObject) throws Default200Exception {
        String hotelid = jsonObject.getString("hotelid");
        String config = jsonObject.getString("config");
        String key2 = "targetnumconfig:" + hotelid;
        redisUtil.set(key2, config);
        return R.ok();
    }

    @PostMapping("/deldaykey")
    public R deldaykey(@RequestBody JSONObject jsonObject) throws Default200Exception {
        String hotelid = jsonObject.getString("hotelid");
        String ymd = jsonObject.getString("ymd");
        String key2 = "calcheck:" + hotelid + ":" + ymd;
        redisUtil.del(key2);
        return R.ok();
    }


    public static List<DayInfo> generateCalendarData(int year, int month) {
        YearMonth yearMonth = YearMonth.of(year, month);
        int lengthOfMonth = yearMonth.lengthOfMonth();
        List<DayInfo> calendarData = new ArrayList<>();


        LocalDate today = LocalDate.now();
        // 如果传入的年份和月份是当前月，则只返回到昨天的日期
        if (year == today.getYear() && month == today.getMonthValue()) {
            lengthOfMonth = today.getDayOfMonth() - 1; // 只返回到昨天
        }

        // 添加当月的所有日期
        for (int day = 1; day <= lengthOfMonth; day++) {
            LocalDate date = yearMonth.atDay(day);
            Date date1 = convertToDateViaInstant(date);
            calendarData.add(new DayInfo(date1, date.getDayOfWeek().getDisplayName(TextStyle.FULL, Locale.CHINA)));
        }
        return calendarData;
    }

    public static Date convertToDateViaInstant(LocalDate dateToConvert) {
        return Date.from(dateToConvert.atStartOfDay()
                .atZone(ZoneId.systemDefault())
                .toInstant());
    }

    public static String formatDate(Date date, String pattern) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        return simpleDateFormat.format(date);
    }
}


@Data
@NoArgsConstructor
@AllArgsConstructor
class DayInfo implements Serializable {

    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date date;
    private String dayOfWeek;
    List<CheckDate> checklist;

    public DayInfo(Date date, String dayOfWeek) {
        this.date = date;
        this.dayOfWeek = dayOfWeek;

    }
}


@Data
@NoArgsConstructor
@AllArgsConstructor
class CheckDate implements Serializable {
    private String tagetnum;
    private String realnum;
    private String name;
    private String state;
}
